using System;
using System.Data;
using System.Xml;

using OR.Reuse.Persistence;

using Derived = OR.Lazarus.Library.DataTier.Source;

namespace OR.Lazarus.Library.DataTier.Source.Lazarus
{
	/// <summary>
	/// Defines a method on an object.  Currently supported method types are Create, Update, Get, List and Custom.
	/// </summary>
   public class MethodDetail : EntityBase
   {
		protected System.String mName;
		protected string mMethodType;
		protected string mObjectName;
		protected string mDBName;
		protected string mFilter;
		protected string mDescription;
	
		protected Derived.PermissionCollection mPermissions;
		protected Derived.EffectObjectRefCollection mAffectedObjects;
		protected Derived.FilterCollection mFilters;
		protected Derived.ParameterCollection mParameters;

		public MethodDetail()
		{
			mPermissions = new Derived.PermissionCollection();
			mPermissions.ParentEntity = this;
			mAffectedObjects = new Derived.EffectObjectRefCollection();
			mAffectedObjects.ParentEntity = this;
			mFilters = new Derived.FilterCollection();
			mFilters.ParentEntity = this;
			mParameters = new Derived.ParameterCollection();
			mParameters.ParentEntity = this;
	
		}
	
		/// <summary>
		/// Specifies a unique name for the entity.
		/// </summary>
		public System.String Name
		{
			get
			{
				return ( mName );
			}
			set
			{
				mName = value;
			}
		}

		/// <summary>
		/// Defines an operation type for the method.  Valid Method Types are: * Create: A new instance of the object is created.  Parameters will be all fields, with auto-generating fields returned as output params. * Update: An existing instance of the object is modified.  The parameter will be the primary key value of the object. * Get: A single existing instance of the object is returned.  The parameter will be any unique key of the object. * List: A collection of existing object instances is returned.  The parameters may be specified to define filters for this list.
		/// </summary>
		public string MethodType
		{
			get
			{
				return ( mMethodType );
			}
			set
			{
				mMethodType = value;
			}
		}

		/// <summary>
		/// Defines an the method's name when used as an object method (in OOP, Customer.Create).
		/// </summary>
		public string ObjectName
		{
			get
			{
				return ( mObjectName );
			}
			set
			{
				mObjectName = value;
			}
		}

		/// <summary>
		/// Defines an the method's name when used as a non-structured method (in SQL, CustomerCreate).
		/// </summary>
		public string DBName
		{
			get
			{
				return ( mDBName );
			}
			set
			{
				mDBName = value;
			}
		}

		/// <summary>
		/// Specifies a field to filter on.
		/// </summary>
		public string Filter
		{
			get
			{
				return ( mFilter );
			}
			set
			{
				mFilter = value;
			}
		}

		/// <summary>
		/// Provides a long-text description for the entity.
		/// </summary>
		public string Description
		{
			get
			{
				return ( mDescription );
			}
			set
			{
				mDescription = value;
			}
		}

		public Derived.PermissionCollection Permissions
		{
			get
			{
				return ( mPermissions );
			}
			set
			{
				mPermissions = value;
			}
		}

		public Derived.EffectObjectRefCollection AffectedObjects
		{
			get
			{
				return ( mAffectedObjects );
			}
			set
			{
				mAffectedObjects = value;
			}
		}

		public Derived.FilterCollection Filters
		{
			get
			{
				return ( mFilters );
			}
			set
			{
				mFilters = value;
			}
		}

		public Derived.ParameterCollection Parameters
		{
			get
			{
				return ( mParameters );
			}
			set
			{
				mParameters = value;
			}
		}

		public override void LoadXml( XmlElement pSource )
		{
			// Scalar Values
			mName = DataUtility.GetString( pSource, "name" );
			mMethodType = DataUtility.GetString( pSource, "type" );
			mObjectName = DataUtility.GetString( pSource, "object-name" );
			mDBName = DataUtility.GetString( pSource, "db-name" );
			mFilter = DataUtility.GetString( pSource, "filter" );
			XmlElement vDescription = ( XmlElement )pSource.SelectSingleNode( "lz:description", PersistenceConfig.Namespaces );
			
			if ( vDescription != null )
			{
				mDescription = vDescription.InnerText;
			}
			
			XmlElement vPermissions = ( XmlElement )pSource.SelectSingleNode( "lz:permissions", PersistenceConfig.Namespaces );
			
			if ( vPermissions != null )
			{
				mPermissions.LoadXml( vPermissions );
			}
			XmlElement vAffectedObjects = ( XmlElement )pSource.SelectSingleNode( "lz:method-effects", PersistenceConfig.Namespaces );
			
			if ( vAffectedObjects != null )
			{
				mAffectedObjects.LoadXml( vAffectedObjects );
			}
			XmlElement vFilters = ( XmlElement )pSource.SelectSingleNode( "lz:method-filters", PersistenceConfig.Namespaces );
			
			if ( vFilters != null )
			{
				mFilters.LoadXml( vFilters );
			}
			XmlElement vParameters = ( XmlElement )pSource.SelectSingleNode( "lz:method-params", PersistenceConfig.Namespaces );
			
			if ( vParameters != null )
			{
				mParameters.LoadXml( vParameters );
			}
		}
		
		public override XmlElement SaveXml( XmlDocument p_docContext )
		{
			XmlElement vNewElement	= p_docContext.CreateElement( "lz", "method", "http://schemas.icitadel.com/Lazarus/Source.xsd" );

			// Scalar Values
			if ( !String.IsNullOrEmpty( mName ) )
			{
				vNewElement.SetAttribute( "name", mName );
			}
					
			if ( !String.IsNullOrEmpty( mMethodType ) )
			{
				vNewElement.SetAttribute( "type", mMethodType );
			}
					
			if ( !String.IsNullOrEmpty( mObjectName ) )
			{
				vNewElement.SetAttribute( "object-name", mObjectName );
			}
					
			if ( !String.IsNullOrEmpty( mDBName ) )
			{
				vNewElement.SetAttribute( "db-name", mDBName );
			}
					
			if ( !String.IsNullOrEmpty( mFilter ) )
			{
				vNewElement.SetAttribute( "filter", mFilter );
			}
					
			if ( !String.IsNullOrEmpty( mDescription ) )
			{
				XmlElement	vDescription = p_docContext.CreateElement( "lz", "description", "http://schemas.icitadel.com/Lazarus/Source.xsd" );
				vDescription.InnerText = mDescription;
				vNewElement.AppendChild( vDescription );
			}
					

			// Collections
			
			XmlElement	vCollection	= null;
			
			vCollection = mPermissions.SaveXml( p_docContext );
			if ( vCollection != null )
			{
				vNewElement.AppendChild( vCollection );
			}
			
			vCollection = mAffectedObjects.SaveXml( p_docContext );
			if ( vCollection != null )
			{
				vNewElement.AppendChild( vCollection );
			}
			
			vCollection = mFilters.SaveXml( p_docContext );
			if ( vCollection != null )
			{
				vNewElement.AppendChild( vCollection );
			}
			
			vCollection = mParameters.SaveXml( p_docContext );
			if ( vCollection != null )
			{
				vNewElement.AppendChild( vCollection );
			}

			return ( vNewElement );
		}

		public virtual object Clone()
		{
			Derived.MethodDetail v_oReturn = new Derived.MethodDetail();
			
			v_oReturn.Name = mName;
			v_oReturn.MethodType = mMethodType;
			v_oReturn.ObjectName = mObjectName;
			v_oReturn.DBName = mDBName;
			v_oReturn.Filter = mFilter;
			v_oReturn.Description = mDescription;
			
			// FK Values

			// Collections

			foreach ( Derived.PermissionDetail vDetail in mPermissions )
			{
				v_oReturn.Permissions.Add( vDetail.CloneTyped() );
			}

			foreach ( Derived.EffectObjectRefDetail vDetail in mAffectedObjects )
			{
				v_oReturn.AffectedObjects.Add( vDetail.CloneTyped() );
			}

			foreach ( Derived.FilterDetail vDetail in mFilters )
			{
				v_oReturn.Filters.Add( vDetail.CloneTyped() );
			}

			foreach ( Derived.ParameterDetail vDetail in mParameters )
			{
				v_oReturn.Parameters.Add( vDetail.CloneTyped() );
			}
			
			return ( v_oReturn );
		}

		public virtual Derived.MethodDetail CloneTyped()
		{
			return ( ( Derived.MethodDetail )this.Clone() );
		}
   }
}
   